package com.mindskip.xzs.context;
//这段代码是一个Java类，它被设计为处理Web应用程序中的用户会话信息。它使用了Spring框架和Spring Security，这是在Java Web开发中常用的安全框架。
//**前端（用户界面）**：
//这个类主要在后端使用，但是它与前端也有一定的交互。前端可以通过调用`setCurrentUser`方法来设置当前请求的用户信息。
// 这个方法会将用户对象存储在当前请求的属性中，这样在后续的请求中，用户信息就可以被获取并使用。
//**后端（服务层）**：
//这个类的主要作用是管理当前请求的用户信息。
// 它通过`getCurrentUser`方法获取当前请求的用户信息。这个方法首先尝试从当前请求的属性中获取用户对象。
// 如果用户对象不存在，那么它会从Spring Security上下文中获取Spring Security用户对象。
// 如果Spring Security用户对象也不存在，那么它将返回null。
// 最后，如果成功从数据库中获取到了用户对象，它会将这个用户对象重新设置到当前请求的属性中。
//它可以在整个会话期间都保持用户信息的一致性，无论是在同一个请求中还是在下一个请求中。此外，它还允许前端和后端共享用户信息，从而使得开发人员可以更容易地处理用户认证和授权问题。
import com.mindskip.xzs.domain.User; // 导入用户类
import com.mindskip.xzs.service.UserService; // 导入用户服务类
import org.springframework.beans.factory.annotation.Autowired; // 导入Spring框架中的自动注入注解
import org.springframework.security.core.context.SecurityContextHolder; // 导入Spring Security中的安全上下文持有者类
import org.springframework.stereotype.Component; // 导入Spring框架中的组件注解
import org.springframework.web.context.request.RequestAttributes; // 导入Spring Web中的请求属性类
import org.springframework.web.context.request.RequestContextHolder; // 导入Spring Web中的请求上下文持有者类

/**
 * Web上下文类，用于管理当前请求的用户信息
 */
@Component
public class WebContext {
    // 定义一个常量用于存储用户属性的键
    private static final String USER_ATTRIBUTES = "USER_ATTRIBUTES";

    // 自动注入用户服务
    private final UserService userService;

    /**
     * 构造器注入用户服务
     *
     * @param userService 用户服务实例
     */
    @Autowired
    public WebContext(UserService userService) {
        this.userService = userService;
    }

    /**
     * 设置当前请求的用户信息
     *
     * @param user 用户实例
     */
    public void setCurrentUser(User user) {
        // 将用户对象存储在当前请求的属性中
        RequestContextHolder.currentRequestAttributes().setAttribute(USER_ATTRIBUTES, user, RequestAttributes.SCOPE_REQUEST);
    }

    /**
     * 获取当前请求的用户信息
     *
     * @return 当前用户实例，如果用户不存在返回null
     */
    public User getCurrentUser() {
        // 从当前请求的属性中获取用户对象
        User user = (User) RequestContextHolder.currentRequestAttributes().getAttribute(USER_ATTRIBUTES, RequestAttributes.SCOPE_REQUEST);

        // 如果用户对象为空，从Spring Security上下文中获取用户信息
        if (null == user) {
            // 从安全上下文中获取Spring Security用户对象
            org.springframework.security.core.userdetails.User springUser = (org.springframework.security.core.userdetails.User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

            // 如果Spring Security用户对象为空，返回null
            if (null == springUser) {
                return null;
            }

            // 根据用户名从数据库中获取用户对象
            user = userService.getUserByUserName(springUser.getUsername());

            // 如果用户对象不为空，将其设置到当前请求的属性中
            if (null != user) {
                setCurrentUser(user);
            }
        }
        return user;
    }
}
